const { ccclass, property, menu } = cc._decorator;

@ccclass
@menu('Prefabs/BoomWithCamera/BoomWithCamera')
export default class BoomWithCamera extends cc.Component {

    @property({ type: cc.Node, tooltip: 'arrow list' })
    arrowNode: cc.Node = null;

    @property({ type: cc.Camera, tooltip: 'camera' })
    camera: cc.Camera = null;

    @property({ type: cc.Graphics, tooltip: 'camera info' })
    cameraInfo: cc.Graphics = null;

    @property({ type: cc.Sprite, tooltip: 'renderTexture' })
    renderTexture: cc.Sprite = null;

    @property({ type: cc.Node, tooltip: 'camera node' })
    cameraNode: cc.Node = null;

    /** 摄像机在正交投影模式下的视窗大小 MxM (宽高一致) */
    private cameraOrthoSize: number = 1;

    /** mini camera position */
    private cameraPos: cc.Vec3 = cc.v3(0, 0, 100);

    private _renderTexture: cc.RenderTexture = new cc.RenderTexture();

    private _touchStartPosition: cc.Vec2 = new cc.Vec2(0, 0);


    start() {
        this._initRenderTexture();
        this.addEmitEvent();

        let orthoSize = this.arrowNode.width > this.arrowNode.height ? this.arrowNode.width : this.arrowNode.height;
        this.cameraOrthoSize = orthoSize;

        let position = new cc.Vec3(this.arrowNode.x, this.arrowNode.y, 100);
        this.camera.orthoSize = this.cameraOrthoSize / 2;
        this.camera.node.position = position;
        this.cameraPos = position;

        this.cameraNode.position = new cc.Vec3(this.cameraPos.x + this.arrowNode.width / 2, this.cameraPos.y, 1);

        cc.resources.load('shader/BlackHole/BlackHole', cc.Material, (err: Error, res: cc.Material) => {
            if (err) { cc.error(err); return; }

            this.renderTexture.setMaterial(0, res);
        })
    }

    onBtnPlay() {
        // camera rendertexture
        // shader
        let arrowList: cc.Node[] = [];
        for (let i = 0; i < 8; i++) {
            let item: cc.Node = this.arrowNode.getChildByName(String(i));
            arrowList.push(item);
        }


        for (let i = 0; i < arrowList.length; i++) {
            let pos: cc.Vec3 = arrowList[i].position;
            cc.tween(arrowList[i])
                .to(0.2, { position: cc.v3(pos.x * 2, pos.y * 2, 0) })
                .start();
        }
    }

    onBtnReset() {
        // for (let i = 0; i < this.arrowList.length; i++) {
        //     let pos: cc.Vec3 = this.arrowList[i].position;
        //     this.arrowList[i].position = cc.v3(pos.x / 2, pos.y / 2, 0);
        // }
    }

    private _initRenderTexture() {
        let { width: canvasWidth, height: canvasHeight } = this.arrowNode;
        let width = canvasWidth;
        let height = canvasHeight;

        this._renderTexture.initWithSize(width, height);
        this.camera.targetTexture = this._renderTexture;

        let spriteFrame = new cc.SpriteFrame();
        spriteFrame.setTexture(this._renderTexture);
        this.renderTexture.spriteFrame = spriteFrame;
        let rect = cc.rect(0, 0, 66, 66);
        spriteFrame.setRect(rect);
        this.renderTexture.node.setContentSize(rect.size);
    }

    update(dt: number) {
        // let { width: canvasWidth, height: canvasHeight } = cc.Canvas.instance.node;
        // let deviceWidth = canvasWidth, deviceHeight = canvasHeight;
        // if (!CC_EDITOR) {
        //     deviceWidth = cc.game.canvas.width / cc.view.getScaleX();
        //     deviceHeight = cc.game.canvas.height / cc.view.getScaleY();
        // }

        let orthoHeight = this.cameraOrthoSize;
        let orthoWidth = orthoHeight * (this._renderTexture.width / this._renderTexture.height);

        this.cameraInfo.clear();

        // draw mini camera border
        let renderTextureNode = this.renderTexture.node;
        let rectX = renderTextureNode.x - renderTextureNode.width / 2;
        let rectY = renderTextureNode.y - renderTextureNode.height / 2;
        this.cameraInfo.rect(rectX, rectY, renderTextureNode.width, renderTextureNode.height);
        this.cameraInfo.strokeColor = cc.Color.YELLOW;
        this.cameraInfo.stroke();

        // dram mini camera ortho size
        rectX = this.cameraPos.x - orthoWidth / 2;
        rectY = this.cameraPos.y - orthoHeight / 2;
        this.cameraInfo.rect(rectX, rectY, orthoWidth, orthoHeight);
        this.cameraInfo.strokeColor = cc.Color.BLUE;
        this.cameraInfo.stroke();
    }

    onTouchStart(evt: cc.Event.EventTouch) {
        let pos = evt.getLocation();
        this._touchStartPosition = new cc.Vec2(this.cameraNode.x, this.cameraNode.y);
        let nodePoint = this.cameraNode.parent.convertToNodeSpaceAR(new cc.Vec3(pos.x, pos.y, 1));
        this.cameraNode.position = nodePoint;

        let camPos = new cc.Vec3(nodePoint.x - this.arrowNode.width / 2, nodePoint.y, 1);
        this.camera.node.position = camPos;
        this.cameraPos = camPos;
    }

    onTouchMove(evt: cc.Event.EventTouch) {
        let pos = evt.getLocation();
        this._touchStartPosition = new cc.Vec2(pos.x, pos.y);
        let nodePoint = this.cameraNode.parent.convertToNodeSpaceAR(new cc.Vec3(pos.x, pos.y, 1));
        this.cameraNode.position = nodePoint;

        let camPos = new cc.Vec3(nodePoint.x - this.arrowNode.width / 2, nodePoint.y, 1);
        this.camera.node.position = camPos;
        this.cameraPos = camPos;
    }

    addEmitEvent() {
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    }
}
